
#include "DSPEncoder.h"


void main()
{

	inits();
	
    /* Bind the PIPs to LIO channels */
    PLIO_new(&plioRx, &pipRx, LIO_INPUT, controller, NULL);
    PLIO_new(&plioTx, &pipTx, LIO_OUTPUT, controller, NULL);

    /*
     * Prime the transmit side with buffers of silence.
     * The transmitter should be started before the receiver.
     * This results in input-to-output latency being one full
     * buffer period if the pipes is configured for 2 frames.
     */
    PLIO_txStart(&plioTx, PIP_getWriterNumFrames(&pipTx), 0);

    /* Prime the receive side with empty buffers to be filled. */
    PLIO_rxStart(&plioRx, PIP_getWriterNumFrames(&pipRx));

	
    /* exit from main into the DSP/BIOS idle loop */
	DSK5416_LED_on(3); 
}

Void synchronization (Void)
{
	const short *waveletBuffer = buffer0;
/*	int previous = 0;
	int next = 0;
  	int time = 0;*/
	unsigned previous = 0;
	unsigned next = 0;
	unsigned tiempo = 0;
//	unsigned us = CLK_countspms()/1000;
	unsigned us = CLK_countspms();
//	unsigned valor = MARK_SAMPLES-SYN_SIZE;

	while (1)
	{
		SEM_pend(&semSYN,SYS_FOREVER);
/*		previous = TSK_time();*/
//		previous = CLK_gethtime();
//		previous = CLK_gethtime()/us;
		putSynMark (waveletBuffer+MARK_SAMPLES-SYN_SIZE);
//		testSynMark (waveletBuffer+128);
/*		next = TSK_time();*/
//		next = CLK_gethtime()/us;
//		next = CLK_gethtime();
//		LOG_printf (&trace,"SYN: status finishing previous: %d ",previous);
//		LOG_printf (&trace,"SYN: status finishing next: %d ",next);

//		time = next - previous;
/*		tiempo = next - previous;
		LOG_printf (&trace,"SYN: status finishing is: %d. time: %d ",status,tiempo);
		LOG_printf (&trace,"SYN: status finishing us: %d",us);*/
	}
}


//#define NUMBER 1
double buff[MOSTRES];
double approxk[SPEC_SIZE],detailk[SPEC_SIZE];

Void encode (Void)
{
	Int j;
	const short *waveletBuffer = buffer1;
	int previous = 0;
	int next = 0;
	int time = 0;

	while (1)
	{
		SEM_pend(&semWavelet,SYS_FOREVER);
		DSK5416_LED_toggle(1);

	//	previous = TSK_time();
		embedMethod (waveletBuffer,7);
	/*	next = TSK_time();
		time = next - previous;
		LOG_printf (&trace,"WATERMARK: status finishing is: %d. time is: %d",status,time);*/
	}	
}

Void sendToHost (Void)
{
	Int i;

	short * bufferToSend;
	for (;;)
	{
		SEM_pend(&semSendToHost,SYS_FOREVER);

		RTDX_enableOutput(&ochan);

		bufferToSend = getBuffer(status);

		for (i=0; i<MARK_SAMPLES; i++)
		{
			if ( !RTDX_write( &ochan, bufferToSend++, 2) ) {
	    //  	   fprintf(stderr,"\nError: RTDX_write() failed!\n");
			 	LOG_error("echo: Data could not be sent!", 0);
	      	  	abort();
			}

	        /* Wait for data transfer                           */
		//	#if 0
	        while ( RTDX_writing != NULL ) {
	                #if RTDX_POLLING_IMPLEMENTATION
	                        /* Call Poll to do data transfer    */
	                        RTDX_Poll();
	                #endif
	        }
		//	#endif

		}
		RTDX_disableOutput(&ochan);
	}
}

Void reading (Void)
{
	Int i, size;
	short *src,*dst;
	short * selectedBuffer;
//	unsigned previous = 0;
//	unsigned next = 0;
//	unsigned tiempo = 0;
//	unsigned us = CLK_countspms()/1000;


//	previous = CLK_gethtime()/us;

	DSK5416_LED_toggle(2);

	status>=(MAX_BUFFERS-1)? status=0:status++;
//	readingBuffer = getBuffer(status);
	selectedBuffer = getBuffer(status);
#ifdef SEND_DATA_TO_HOST
	SEM_post(&semSendToHost);
#endif

    /*
     * Check that the precondions are met, that is pipRx has a buffer of
     * data and pipTx has a free buffer.
     */
    if (PIP_getReaderNumFrames(&pipRx) <= 0) {
        LOG_error("echo: No reader frame!", 0);
        return;
    }
    if (PIP_getWriterNumFrames(&pipTx) <= 0) {
        LOG_error("echo: No writer frame!", 0);
        return;
    }

    /* get the full buffer from the receive PIP */
    PIP_get(&pipRx);
    src = PIP_getReaderAddr(&pipRx);
    size = PIP_getReaderSize(&pipRx) * sizeof(short);

    /* get the empty buffer from the transmit PIP */
    PIP_alloc(&pipTx);
    dst = PIP_getWriterAddr(&pipTx);

	if (size>MARK_SAMPLES)
	{
    	LOG_error("Internal buffers not prepared for size bigger than MARK_SAMPLES!", 0);
		abort();
	}

    for (i = 0; i < size; i++) {
		*dst++ = *selectedBuffer;
		*selectedBuffer++ = *src++;
    }     

    /* Record the amount of actual data being sent */
    PIP_setWriterSize(&pipTx, PIP_getReaderSize(&pipRx));

    /* Free the receive buffer, put the transmit buffer */
    PIP_free(&pipRx);
    PIP_put(&pipTx);

//	next = CLK_gethtime()/us;
//	tiempo = next - previous;
//	LOG_printf(&trace, "int time is: %d", tiempo);
	if (status == 1)// && time > 1000)  //time to send an embedded message
	{
		SEM_post(&semWavelet);
	} else if (status == 0) //Synchronize mark is inserted at buffer 0
	{
		SEM_post(&semSYN);
	}
}

DSK5416_DMA_PCM3002_Setup mySetup;

/*
 *  ======== main ========
 */
void inits()
{
	Int i;
	DSK5416_PCM3002_CodecHandle ch;
		
DSK5416_PCM3002_Config conf = {
    0x010d,   
    0x010d,   
    0x0000,   
    0x0000                                                                   \
};
/*DSK5416_PCM3002_Config conf = {
    0x0100,   
    0x01ff,   
    0x0000,   
    0x0000                                                                   \
};*/

	
	DWT_INIT();

	status = MAX_BUFFERS;
	for (i=0;i<MARK_SAMPLES;i++)
	{
		buffer0[i] = 0;
		buffer1[i] = 0;
		buffer2[i] = 0;
		buffer3[i] = 0;
		buffer4[i] = 0;
		buffer5[i] = 0;
		buffer6[i] = 0;
		buffer7[i] = 0;
		buffer8[i] = 0;
		buffer9[i] = 0;
		buffer10[i] = 0;
		buffer11[i] = 0;
		buffer12[i] = 0;
		buffer13[i] = 0;
		buffer14[i] = 0;
		buffer15[i] = 0;
		buffer16[i] = 0;
		buffer17[i] = 0;
		buffer18[i] = 0;
		buffer19[i] = 0;
		buffer20[i] = 0;
		buffer21[i] = 0;
		buffer22[i] = 0;
		buffer23[i] = 0;
		buffer24[i] = 0;
		buffer25[i] = 0;
		buffer26[i] = 0;
		buffer27[i] = 0;
//		buffer5[i] = 0;
	}

    /*
     * CONTROLLER_init() initializes the device controller.
     * See CONTROLLER_init() in the linker command file.
     */ 
	DSK5416_init();
	DSK5416_LED_init();

    /*
     * CONTROLLER_setup() configures device with parameter.
     * If NULL is specified then the default settings will be used.
     * Set CONTROLLER_setup() in the linker command file.
     * The LIO controller comes from the BSL lib (ex. c5400\dsk5416\lib).
     */

	DSK5416_DMA_PCM3002_init();


mySetup.pcm3002 = conf;


	
	ch = DSK5416_PCM3002_openCodec (0,&mySetup.pcm3002);
//		ch = DSK5416_PCM3002_openCodec (1,&DSK5416_DMA_PCM3002_SETUP.pcm3002);

	DSK5416_PCM3002_setFreq(ch, 8000);

//	DSK5416_PCM3002_closeCodec (ch);

	DSK5416_DMA_PCM3002_setup(&mySetup);
//	DSK5416_DMA_PCM3002_setup(&DSK5416_DMA_PCM3002_SETUP);
	// If NULL it is used the default object also.
	//DSK5416_DMA_PCM3002_setup(NULL);

//	TARGET_INITIALIZE();
}

short *getBuffer(unsigned int n)
{
	if (n>MAX_BUFFERS-1) n=n%MAX_BUFFERS;

	switch (status)
	{
		case 0:
			return buffer0;
		case 1:
			return buffer1;
		case 2:
			return buffer2;
		case 3:
			return buffer3;
		case 4:
			return buffer4;
		case 5:
			return buffer5;
		case 6:
			return buffer6;
		case 7:
			return buffer7;
		case 8:
			return buffer8;
		case 9:
			return buffer9;
		case 10:
			return buffer10;
		case 11:
			return buffer11;
		case 12:
			return buffer12;
		case 13:
			return buffer13;
		case 14:
			return buffer14;
		case 15:
			return buffer15;
		case 16:
			return buffer16;
		case 17:
			return buffer17;
		case 18:
			return buffer18;
		case 19:
			return buffer19;
		case 20:
			return buffer20;
		case 21:
			return buffer21;
		case 22:
			return buffer22;
		case 23:
			return buffer23;
		case 24:
			return buffer24;
		case 25:
			return buffer25;
		case 26:
			return buffer26;
		case 27:
			return buffer27;
	}

	abort();
	return 0;
}
